Designs by Sabi*

DRAMATIZED CASE STUDY This is a reconstructed presentation of real product-design work. To protect confidentiality, the domain, data, terminology, visual details, and other identifying information have been abstracted or recreated as Meridian Commerce, a fictional retail platform. The design challenges, decisions, tradeoffs, and lessons reflect my actual work.

A tool for building Audience Segments. Customer groups that power campaigns, offers, and loyalty targeting across Meridian Commerce. This is a redesign, not a greenfield build. The tool it replaces had a real, specific complaint attached to it: people couldn’t tell what a segment actually did anymore. It let logic nest four levels deep, exposed operators like NaN and NOR straight from the query engine, and had quietly become something only its original builder could read with confidence.

The challenge wasn’t adding capability. It was taking capability away in the right places, and proving where “the right places” actually were.


My Role

  • Product Design / UX
  • Research, interaction design, prototyping
  • Team: Collaborated with Product Manager, Executive Stakeholders, Developers, and with 2 fellow Product Designers
  • Timeline: In progress

The Challenge

  • The existing builder let logic nest arbitrarily deep, and real segments had drifted there. Not because the complexity was needed, but because nothing stopped it from accumulating
  • Operators like NaN and NOR were leaking straight from the underlying query engine into a tool marketers and revenue strategists were expected to use confidently
  • The core complaint wasn’t “it can’t do what I need.” It was “I can’t tell what it’s doing.”

Before touching the interface, the question was whether “too deep” was actually true, or just a feeling. So the team ran an audit.

The Audit

The team ran ran an AI-assisted query against the production segment database, bucketing every existing segment by its actual nesting depth, rather than designing around a guess. Of roughly 300 live segments, only 5 used a fourth level of nesting. All 5 were reviewed individually, and all 5 could be re-architected to fit within 3 levels by combining two already-existing, shallower segments together instead of nesting raw conditions deeper.

That’s the evidence a depth cap rests on: not an opinion about what feels too deep, but a measurement of what the deepest real segments actually needed once someone was willing to rebuild them properly. It also set the bar for everything that followed. If the redesign made those 5 cases meaningfully harder to express, it would have failed on its own terms.


The Design Question

How do you let a segment express real complexity without letting it become something only its author can read?

A hard cap on nesting solves legibility and risks capability. Unlimited nesting solves capability and is exactly what produced the tool being replaced. Neither answer on its own was going to work.


Exploring the Directions

Considered: a two-mode split: a flat “quick” filter list and a separate “advanced” builder, the way some general-purpose tools handle this. I didn’t take this direction. It solves the problem by hiding it behind a toggle, and this project already had a stronger answer available: let depth itself carry the cost, so no one has to choose a mode before they know how complex their segment will actually be.

What I built instead: one surface, three levels, uncapped breadth.

  • Depth is capped at 3 — a flat root list, one nested group, one group nested inside that. This is the number the audit justified.
  • Breadth is not capped. Someone can add twenty sibling conditions or groups at any single level without touching the depth limit at all. A long flat list, however long, stays legible and the cap governs the axis that was actually causing the problem.
  • Every group carries a plain-language toggle: “All of these are true” or “Any of these are true”. Never raw AND/OR, and certainly never NaN or NOR.
  • The deepest group’s + group control is disabled once it’s three levels in. The cap isn’t a rule someone has to remember; it’s a control that simply stops being there.

The escape valve: composition, not depth. A condition can reference an existing, already-built segment directly rather than rebuilding that logic from scratch. This is how real complexity gets expressed without ever needing a fourth level: push it sideways into named, reusable pieces instead of downward into a tree nobody can hold in their head. It’s the direct answer to what the audit’s 5 outlier segments actually needed.


Two Decisions That Hold the Model Together

1. The cap is enforced, not requested

The depth limit lives at the data layer, not just in the UI. A fourth level is structurally impossible to write, through any path: the builder, an import, an API call. The interface just makes sure no one ever has to find that out the hard way; the + group control disappears exactly where the limit is.

Grouping conditions makes it easy for users to parse the the segment's stucture.

2. Composition reuses is / is not instead of inventing new logic

A segment reference behaves like any other condition — Segment is Platinum Members, or Segment is not Lapsed High-Value Customers for exclusion. I considered adding a separate whole-group negation control (a “Match / Does not match” toggle on any group, not just a reference) to handle “everyone except this entire nested cluster.” I cut it. The audit already showed how rarely real segments reach that level of complexity, and the honest cost of the feature wasn’t earned by a case that rare. If usage data after launch says otherwise, that’s a deliberate future addition.


Considered and Cut: A “Needs Review” Status

A segment that depends on something broken seemed to want its own status, a third state alongside Draft and Active. I cut it. Instead, changing a segment’s status is gated by role permission, which gets the actual functionality being protected without a new workflow state for anyone to learn. Same shape as the group-negation cut above: a plausible feature, weighed against a simpler existing mechanism, set aside until real usage proves it’s needed.


Making “At a Glance” Actually True

The list view carries the same signal Meridian Commerce’s loyalty tooling already relies on: a count that tells you something’s structure before you open it. A dependency metric is used to tracked campaigns, offers, and other segments directly consuming a segment.

 The cards that shipped instead: Active Segments, Customers Reached, In Campaigns & Offers, Total Revenue Influenced to say what the collection is doing for the business.

The list’s summary cards went through their own correction worth naming. My first pass measured the segments themselves. How many used composition, how many sat at the depth cap. Structurally accurate, but it was answering the wrong question for the audience actually scanning this list: marketers and revenue strategists care what these segments are and do, not how they’re built underneath. The cards that shipped instead: Active Segments, Customers Reached, In Campaigns & Offers, Total Revenue Influenced to say what the collection is doing for the business.


Where This Overlaps With Loyalty And What I’m Not Fixing Yet

Building this alongside the loyalty rules work surfaced something I wasn’t looking for: Rule Programs can only target by Location and Tier, hardcoded into a plain-sentence Base Rule. Segments can express almost anything. A strategist who builds “Platinum members who opted into email” as a segment has no way to actually use that audience inside a Rule Program. The same “who does this apply to” question, solved twice, at two very different levels of power.

I’m not fixing this now, and I want to be specific about why. The honest first step is the same one that justified the depth cap: audit how many real Rule Programs would actually need segment-level targeting before assuming the answer is “add a reference to any segment as a new kind of condition.” If a Rule Program’s Base Rule stays a plain sentence by default which is the reason it’s fast and a Segment reference becomes one more option alongside Location and Tier, that’s the shape I’d build. But I’d rather show that as a validated next step than as a feature I added because it seemed obviously right. It’s also, quietly, a proof the dependency model already generalizes: a Rule Program referencing a Segment is just one more consumer in the same used_in bucket every campaign and offer already sits in. Nothing new to build there. Just one more thing that would use what’s already built.


A Responsible Approach to AI in This Tool

The audit that justified the depth cap used AI-assisted analysis of the database. It felt wrong to write that into this case study and then say nothing about where AI belongs in the product itself. Here’s where I actually land, held to the same bar as everything else here: does it make something more legible, or does it just make something sound more advanced.

Worth building: a natural-language drafting aid. Someone describes a segment in plain English; AI proposes a structure but always opens in the real builder for review. Nothing saves until a person reads the tree and the plain-language summary and confirms it. It never touches a live segment on its own.

Worth explicitly not building: AI-generated summary sentences. The builder already produces those deterministically from the segment’s own structure, and a template is more trustworthy than a model for a job with no real ambiguity to resolve. Declining an AI feature here, on purpose, is worth stating outright. It’s the same discipline as the other cuts in this project, not an oversight.

Worth flagging as a future direction, not a commitment: advisory anomaly detection — surfacing something like “this combination hasn’t matched any customers in similar segments” as a dismissible hint, never an automatic correction. This is the one I’d sit with longest before building, since pattern-matching over historical data edges toward a black box, which is precisely what this entire redesign was fighting.

Explicit non-goal: no autonomous segment creation or publishing. Nothing edits or activates a segment without a person choosing to.


What Changed

  • For users: a segment’s complexity is now visible before anyone opens it. In the list, on its own page, and in what it’s allowed to do
  • For the product: one flexible object: conditions, groups, a depth cap, and composition to replace a tool whose complexity had no ceiling and no explanation
  • For the team/business: [Outcome to substantiate once shipped]
  • Evidence: [Usability findings, stakeholder validation, whatever exists at time of writing]

Measuring the work

  • Time to build a segment with zero nested groups (should stay effectively unchanged from a simple filter list)
  • Ratio of segments using composition vs. raw nesting, over time as a proxy for whether the escape valve is actually being used as intended
  • How many segments sit at the depth cap, tracked continuously. The same measurement the redesign was justified by, now running as an ongoing check rather than a one-time audit.

What I Learned

The Rule Programs overlap taught me something about the shape of this whole body of work rather than about this tool specifically. Four case studies built as one connected product surfaced a contradiction that four case studies built in isolation never would have: two systems, designed months apart, quietly reinventing the same targeting logic. That’s not a flaw to route around — it’s the one piece of evidence that I’ve been thinking about this as a product, not just as a series of screens.